﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using Game.Klassen;
using Game.Classes;

namespace Game
{
    public class Player
    {
        #region Initialisierung
        //Eigenschaften
        public Point    offset;
        public Point    pos;
        public Size     size;
        public Point    bgPos;
        public int      shinePos;
        public int      oxygen;
        public string   name;

        public bool     alreadyFought       = false;
        public bool     enabled             = true;
        public bool     hasKey              = false;
        public bool     stopMoving          = false;
        public string   LastMoveDirection   = "Up";
        public int      turns               = 1;

        public Timer    TimerMove = new Timer();
        public int      StepsMove = 0;

        public Timer    TimerAnimate = new Timer();
        public int      StepsAnimate = 0;

        //Bilder für Animationen
        private Image img;
        public Image moveImg;
        public Image standImg;

        
        

        //Konstruktor
        public Player(string name, int oxygen, Point pos, Image moveImg, Image standImg)
        {
            this.name       = name;
            this.oxygen     = oxygen;
            this.pos        = pos;
            this.size       = new Size(64, 64);
            this.offset     = new Point(0, 0);

            this.moveImg    = moveImg;
            this.standImg   = standImg;
            this.img        = standImg;

            //Timer für Bewegung
            TimerMove.Interval = 5;
            TimerMove.Tick += new EventHandler(moveTimer);
            TimerMove.Enabled = true;

            //Timer für Animation
            TimerAnimate.Interval = 500;
            TimerAnimate.Tick += new EventHandler(animateTimer);
            TimerAnimate.Start();

            //Hintergrundverschiebung anpassen
            setBgPos();
        }
        #endregion

        #region Tools
        //Aktuelles Animationsbild
        public Image getImage()
        {

            return Tools.cropImage(new Rectangle((StepsAnimate * 64), 0, 64, 64), img);
        }

        //Animation weiterschalten
        private void animateTimer(Object sender, EventArgs e)
        {
            if (StepsAnimate + 1 <= img.Width / 64 - 1)
                StepsAnimate++;
            else
                StepsAnimate = 0;
        }

        //Sauerstoff hinzufügen
        public void addOxygen(int value)
        {
            if (oxygen + value > 50)
                oxygen = 50;
            else
                oxygen += value;
        }

        //Sauerstoff entfernen
        public void remOxygen(int value)
        {
            if (oxygen - value < 0)
                oxygen = 0;
            else
                oxygen -= value;
        }

        //Kampf verlieren
        public void loseFight()
        {
            //InfoNachricht ausgeben
            Session.setMessage(name + " hat den Kampf verloren!");

            //Spieler nach oben Bewegen und Sauerstoff halbieren
            this.move("up", false, false);
            this.oxygen = this.oxygen / 2;

            //Sauerstoff verlust darstellen
            for (int x = 0; x < 5; x++)
            {
                Session.bgObjects.Add(new Bubble(new Point(pos.X, pos.Y-1), new Size(Session.rand.Next(5, 20), Session.rand.Next(5, 20))));
                Session.bgObjects.Add(new Bubble(new Point(pos.X, pos.Y-2), new Size(Session.rand.Next(5, 20), Session.rand.Next(5, 20))));
                Session.bgObjects.Add(new Bubble(new Point(pos.X, pos.Y),   new Size(Session.rand.Next(5, 20), Session.rand.Next(5, 20))));
            }

            //Schlüssel verlieren falls vorhanden
            if (hasKey)
            {
                hasKey = false;
                Session.placeNewKey();
            }
        }

        //Animationsmethode für flüssige Bewegungen
        public void moveTimer(Object myObject, EventArgs myEventArgs)
        {
            if (LastMoveDirection == "down")
                if (StepsMove > 0)
                {
                    offset.Y += 4;
                }
                else if (StepsMove == 0)
                {
                    offset   = new Point(0, 0);
                    pos.Y   += 1;
                    enabled  = true;
                    img      = standImg;
                    TimerAnimate.Interval = 500;
                }

            if (LastMoveDirection == "up")
                if (StepsMove > 0)
                    offset.Y -= 4;
                else if (StepsMove == 0)
                {
                    offset = new Point(0, 0);
                    pos.Y -= 1;

                    //Falls möglich weiter Kostenlos nach oben Bewegen
                    Point oben = new Point(pos.X, pos.Y - 1);

                    if (!Tools.playerCollision(oben))
                        if (!Tools.positionCollision(oben) && (pos.Y - 1) >= 0)
                            if(!Tools.containsWhirl(Session.currentPlayer.pos))
                                if(!stopMoving)
                                    move("up", false, true);

                    if (Tools.playerCollision(oben) || Tools.positionCollision(oben) || Tools.containsWhirl(Session.currentPlayer.pos) || stopMoving)
                    {
                        enabled = true;
                        img     = standImg;
                        TimerAnimate.Interval = 500;
                        stopMoving = false;
                    }
                }


            if (LastMoveDirection == "right")
                if (StepsMove > 0)
                    offset.X -= 4;
                else if (StepsMove == 0)
                {
                    offset = new Point(0, 0);
                    pos.X += 1;
                    enabled = true;
                    img = standImg;
                    TimerAnimate.Interval = 500;
                }


            if (LastMoveDirection == "left")
                if (StepsMove > 0)
                    offset.X += 4;
                else if (StepsMove == 0)
                {
                    offset = new Point(0, 0);
                    pos.X -= 1;
                    enabled = true;
                    img = standImg;
                    TimerAnimate.Interval = 500;
                }


            //Animationscounter reduzieren Hintergrund aktualisieren
            setBgPos();

            if(StepsMove >= 0)
                StepsMove--;
        }

        //Hintergrundposition an Spielerposition anpassen
        public void setBgPos()
        {
            bgPos.X = pos.X * -5;
            bgPos.Y = pos.Y * -5;
            shinePos= pos.X * -2;
        }

        //Spieler an Position setzen
        public void setPos(Point pos)
        {
            this.pos = pos;
        }
        #endregion

        #region Bewegungen
        //Spielerbewegungen
        public void move(string direction, bool doesCost, bool playerCollide)
        {
            Point   moveTo;
            int     cost;

            //Position zu Bewegungsrichtung festlegen
            if (direction == "up")
                moveTo = new Point(pos.X, pos.Y - 1);
            else if (direction == "down")
                moveTo = new Point(pos.X, pos.Y + 1);
            else if (direction == "left")
                moveTo = new Point(pos.X - 1, pos.Y);
            else
                moveTo = new Point(pos.X + 1, pos.Y);

            //Kosten für bewegung berechnen
            cost = Session.getMoveCost(moveTo);

            //Bewegungslogik
            if (doesCost)
            {
                if (enabled)
                    if (oxygen >= cost)
                    {
                        if (!playerCollide)
                        {
                            if (!Tools.positionCollision(moveTo))
                                move(moveTo, direction, cost);
                            else
                                Session.setMessage("Der Weg ist blockiert.");
                        }
                        else
                            if (!Tools.playerCollision(moveTo))
                                if (!Tools.positionCollision(moveTo))
                                    move(moveTo, direction, cost);
                                else
                                    Session.setMessage("Der Weg ist blockiert.");
                    }
                    else
                        Session.setMessage("Nicht genügend Sauerstoff.");
            }
            else
                if (!playerCollide)
                {
                    if (!Tools.positionCollision(moveTo))
                        move(moveTo, direction, 0);
                }
                else
                    if (!Tools.playerCollision(moveTo))
                        if (!Tools.positionCollision(moveTo))
                            move(moveTo, direction, 0);
        }

        //Hilfsmethode zu move
        public void move(Point moveTo, string dir, int cost)
        {
            //Animationsbild wechseln
            img = moveImg;
            TimerAnimate.Interval = 100;

            //Pro Kostenfaktor eine Blase aufsteigen lassen
            if(cost > 0)
                for(int x = 0; x < cost; x++)
                    Session.bgObjects.Add(new Bubble(pos, new Size(Session.rand.Next(10, 25), Session.rand.Next(10, 25))));

            enabled             = false;    //Bewegung während der Animation ausschalten
            LastMoveDirection   = dir;      //Letzte bewegungsrichtung speichern
            StepsMove        = 16;       //Schritte der Animation
            oxygen             -= cost;     //Kosten vom Sauerstoffhaushalt abziehen

            //Hintergrundposition aktualisieren
            setBgPos();             
        }
        #endregion
    }
}
